package com.example.springbott.aspactJ;

import com.example.springbott.bean.BaseRespVo;
import com.example.springbott.bean.MarketAdmin;
import com.example.springbott.bean.MarketLog;
import com.example.springbott.bean.MarketOrder;
import com.example.springbott.bean.silic.OrderIdBo;
import com.example.springbott.bean.silic.OrderShipBo;
import com.example.springbott.mapper.MarketApiMapper;
import com.example.springbott.mapper.MarketLogMapper;
import com.example.springbott.mapper.MarketOrderMapper;
import lombok.SneakyThrows;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.Mapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Aspect
@Component
public class OperationLog {
    @Autowired
    MarketLogMapper mapper;
    @Autowired
    MarketApiMapper marketApiMapper;
    @Autowired
    MarketOrderMapper marketOrderMapper;

    @Pointcut("@annotation(com.example.springbott.aspactJ.OperationName)")
    public void pointcut1() {
    }

    @Pointcut("execution(* com..controller..*(..))")
    public void pointcut2() {
    }


    @Around("pointcut1()")
    @SneakyThrows
    @Transactional
    public Object opLog(ProceedingJoinPoint proceedingJoinPoint) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        MarketAdmin subject = (MarketAdmin) SecurityUtils.getSubject().getPrincipal();

        MarketLog marketLog = new MarketLog();

        marketLog.setDeleted(false);
        marketLog.setIp(request.getRemoteHost());
        marketLog.setAddTime(new Date());
        marketLog.setUpdateTime(new Date());
        Object proceed = proceedingJoinPoint.proceed();
        String name = proceedingJoinPoint.getSignature().getName();
        Object target = proceedingJoinPoint.getTarget();
        Class<?> aClass = target.getClass();
        RequestMapping RootRequestMapping = aClass.getAnnotation(RequestMapping.class);
        Method[] declaredMethods = aClass.getDeclaredMethods();
        Method method = null;
        for (int i = 0; i < declaredMethods.length; i++) {
            if (declaredMethods[i].getName().equals(name)) {
                method = declaredMethods[i];
                break;
            }
        }
        Object dispatchMap;
        OperationName annotation = method.getAnnotation(OperationName.class);
        if (method.isAnnotationPresent(RequestMapping.class)) {
            dispatchMap = method.getAnnotation(RequestMapping.class);
        } else if (method.isAnnotationPresent(GetMapping.class)) {
            dispatchMap = method.getAnnotation(GetMapping.class);
        } else {
            dispatchMap = method.getAnnotation(PostMapping.class);
        }

        String rootPath = RootRequestMapping.value()[0];

        String[] value1 = null;
        if (dispatchMap instanceof RequestMapping){
            value1 = ((RequestMapping)dispatchMap).value();
        }else if (dispatchMap instanceof GetMapping){
            value1 = ((GetMapping)dispatchMap).value();
        }else {
            value1 = ((PostMapping)dispatchMap).value();
        }
        String kidPath = value1[0];
        String value = annotation.value();

        if (Integer.parseInt(value) != 1) {
            marketLog.setType(2);
        } else {
            marketLog.setType(1);
        }
        int errno=0;
        if (proceed instanceof BaseRespVo){
           errno = ((BaseRespVo) proceed).getErrno();
        }else if (proceed instanceof com.example.springbott.bean.common.BaseRespVo){
            errno = ((com.example.springbott.bean.common.BaseRespVo) proceed).getErrno();
        }
        if (errno == 0) {
            marketLog.setStatus(true);
        } else {
            marketLog.setStatus(false);
        }
        String path = rootPath + "/" + kidPath;

        if (Integer.parseInt(value) == 3) {
            Object[] args = proceedingJoinPoint.getArgs();

            MarketOrder marketOrder = marketOrderMapper.selectByPrimaryKey(((OrderShipBo) args[0]).getOrderId());
            marketLog.setResult("订单编号" + marketOrder.getOrderSn());
        }

        if (Integer.parseInt(value) == 4) {
            Object[] args = proceedingJoinPoint.getArgs();

            MarketOrder marketOrder = marketOrderMapper.selectByPrimaryKey(((OrderIdBo) args[0]).getOrderId());

            marketLog.setResult("订单编号" + marketOrder.getOrderSn());
        }
        if (Integer.parseInt(value) == 5) {
            Object[] args = proceedingJoinPoint.getArgs();

            String username = ((MarketAdmin) args[0]).getUsername();

            marketLog.setResult(username);
        }





        if ("admin/auth/login".equals(path) && errno != 0) {
            marketLog.setResult("登录失败，用户名密码错误");
        }
        String label= path;

       String www= request.getMethod()+" /"+path;

         label = marketApiMapper.selectLabelByPath(request.getMethod()+" /"+path);
        System.out.println(label);
        if (label==null){
            marketLog.setAction("查询");
        }else {
            marketLog.setAction(label);
        }

        if (subject != null) {
            marketLog.setAdmin(subject.getUsername());
        } else {
            marketLog.setAdmin("admin123");
        }
//        marketLog.setAdmin(subject.getUsername());

        mapper.insert(marketLog);

        return proceed;
    }
}
